﻿using System;
using System.Collections.Generic;
using System.Linq;
using Analyze.Calculator;
using Analyze.Provider;
using Analyze.Service;
using Common.Dao;
using Common.Extension;
using Common.Model;
using log4net;
using Newtonsoft.Json;

namespace Analyze.Script
{
    public class ModelsClassifyScript
    {
        
        private static readonly ILog Log = LogManager.GetLogger(typeof(ModelsClassifyScript));
        
        public static void Run()
        {
            Log.Info("ModelsClassifyScript start");
//            classifyModels = classifyModels.Where(m => m.WordConditionaProbability > 0.02f).ToList();
            var classifier = new BayesClassifier(TrainingDataProvider.GetInstance());

            var list = NewsDao.GetNewsWhereBlockClassifyIsNull();

            try
            {
                foreach (var newse in list)
                {
                    var dictionary = KeywordService.GetKeywords(newse.Title+newse.Abs);
                    newse.Keywords = JsonConvert.SerializeObject(dictionary);
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                throw;
            }


            var noKeywords = NewsDao.GetNewsWhereKeywordsIsNull();

            try
            {
                foreach (var newse in noKeywords)
                {
                    var dictionary = KeywordService.GetKeywords(newse.Title + newse.Abs);
                    newse.Keywords = JsonConvert.SerializeObject(dictionary);
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                throw;
            }

            
            NewsDao.UpdateKeywords(list);
            NewsDao.UpdateKeywords(noKeywords);
            
            List<List<News>> newsList = list.Partition(50).ToList();
            List<News> errorEvents = new List<News>();
            foreach (var news in newsList)
            {
                List<List<string>> words = null;
                try
                {
                    words = SegmentationService.GetWords(news.Select(m => m.Title + "," + m.Abs).ToArray());
                }
                catch (Exception e)
                {
                    errorEvents.AddRange(news);
                    Log.Error("models classify error:");
                    Log.Error("news =" + errorEvents.Select(m => m.ContentId).ToList().List2String());
                    continue;
                }
                
                for (var i = 0; i < words.Count; i++)
                {
                    List<ClassifyResult> classify = classifier.GetClassifyResults(words[i]);
                    news[i].ClassifyResult = JsonConvert.SerializeObject(classify);

                    ClassifyResult firstResult = classify.First();
                    var complexProbility = firstResult.ComplexProbility;
                    if (complexProbility > 1 || complexProbility / classify[1].ComplexProbility > Math.Pow(10, 3))
                    {
                        news[i].BlockClassify = firstResult.Classification;
                    }
                    else
                    {
                        news[i].BlockClassify = "未分类";
                    }
                }
            }
            
            foreach (var news in errorEvents)
            {
                var words = SegmentationService.GetWords(news.Title + news.Abs).Keys.Where(m => m.Length > 1).ToList();

                List<ClassifyResult> classify = classifier.GetClassifyResults(words);
                
                news.BlockClassify = classify.First().Classification;
                news.ClassifyResult = JsonConvert.SerializeObject(classify);
                
                Log.Info("新闻：\r\n" + news.Abs);
                Log.Info("分类：" + classify);
            }
            
            NewsDao.UpdateBlockClassify(list);
            NewsDao.UpdateClassifyResult(list);
            Log.Info("ModelsClassifyScript end");
        }
    }
}